home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / DEMOS / PLP_SMTH.ZIP / INTRO.ASM < prev    next >
Encoding:
Assembly Source File  |  1996-03-21  |  65.6 KB  |  2,629 lines

  1. ; ============================================
  2. ;  4Kb Intro for the Assembly '95 competition
  3. ; ============================================
  4.  
  5. ; Programmed by:
  6. ;    Kim Holviala
  7. ;    Aladininkatu 7 B 19
  8. ;    49400 Hamina
  9. ;    FINLAND
  10.  
  11.  
  12. ; Asm '95 rules for the 4Kb intro:
  13. ;  - Under 4Kb's  (more than enough for anything....)
  14. ;  - Not more than 3 minutes
  15. ;  - Must stop with ESC
  16. ;  - No musics
  17.  
  18.  
  19. ; To compile a .COM file (Turbo Assembler v3.0 -> ):
  20. ;  - Make sure INTRO.ASM and VAR.MAC are present
  21. ;  - TASM /m intro
  22. ;  - TLINK /t intro
  23.  
  24. ; To compile an .EXE with full debug data:
  25. ;  - TASM /m /zi /ddebug intro
  26. ;  - TLINK /v intro
  27.  
  28.  
  29. IDEAL
  30.  
  31. MODEL TINY                              ; One segment is more than enough
  32.  
  33. P386N                                   ; The only way to do it!
  34.  
  35.  
  36. IFDEF debug                             ; .EXE must have an stack
  37.    
  38.    STACK   500h
  39.  
  40. ENDIF
  41.  
  42.  
  43. INCLUDE "var.mac"                       ; Include macros for stack-variables
  44.  
  45.  
  46. ; Variables ===============================================
  47.  
  48. VAR     codesegment,    WORD            ; Current codesegment
  49. VAR     vgasegment,     WORD,   0A000h  ; VGA memory
  50. VAR     virtualscr,     WORD            ; Segment of the virtual screen
  51. VAR     firestartscr,   WORD            ; Needed for the fire-effect
  52.  
  53. VAR     temp,           WORD            ; Temporal storage
  54. VAR     count,          BYTE            ; Counts anything
  55. VAR     power_meter,    WORD            ; Calculates the speed of the computer
  56. VAR     timer,          WORD,   0       ; 60 ticks/sec clock
  57.  
  58. VAR     dot_curr_char,  WORD            ; Current charptr for the dot-scroll
  59. VAR     dot_horiz_place,BYTE,   0       ; Next vertical column to be printed
  60.  
  61. VAR     sin_start_char, WORD            ; Start charptr for the sinus-scroll
  62. VAR     sin_curr_char,  WORD
  63. VAR     sin_horiz_start,BYTE,   0       ; Horizontal starting-place
  64. VAR     sin_sinptr,     BYTE            ; Pointer to the sine-table
  65.  
  66. VAR     x_rotation,     BYTE,   0       ; Rotation around the x-axis
  67. VAR     y_rotation,     BYTE,   0
  68. VAR     z_rotation,     BYTE,   0
  69. VAR     distance,       DWORD,  390000h ; Distance of the 3D-object
  70.  
  71. VAR     center_x,       WORD,   420     ; Place of the 3D-object on screen
  72. VAR     center_y,       WORD,   80
  73.  
  74. VAR     sin_x,          DWORD           ; SIN(x_rotation)
  75. VAR     sin_y,          DWORD
  76. VAR     sin_z,          DWORD
  77. VAR     cos_x,          DWORD
  78. VAR     cos_y,          DWORD
  79. VAR     cos_z,          DWORD
  80.  
  81. VAR     cosz_cosy,      DWORD           ; cos_z * cos_y
  82. VAR     sinz_cosy,      DWORD
  83. VAR     sinz_cosx,      DWORD
  84. VAR     cosz_sinx,      DWORD
  85. VAR     cosz_cosx,      DWORD
  86. VAR     sinz_sinx,      DWORD
  87. VAR     cosy_sinx,      DWORD
  88. VAR     cosy_cosx,      DWORD
  89.  
  90. VAR     matrix0,        DWORD           ; 9 slots for the 3*3 matrix
  91. VAR     matrix1,        DWORD
  92. VAR     matrix2,        DWORD
  93. VAR     matrix3,        DWORD
  94. VAR     matrix4,        DWORD
  95. VAR     matrix5,        DWORD
  96. VAR     matrix6,        DWORD
  97. VAR     matrix7,        DWORD
  98. VAR     matrix8,        DWORD
  99. VAR     matrix9,        DWORD
  100.  
  101. VAR     new_x,          DWORD           ; Rotated x-coordinate (on screen)
  102. VAR     new_y,          DWORD
  103. VAR     new_z,          DWORD
  104.  
  105. VAR     fade_in_progress, BYTE          ; Variables for color-fading
  106. VAR     fade_source,    WORD
  107.  
  108. VAR     morph_source,   WORD            ; Variables for ball-morphing
  109.  
  110. VAR     retadress,      WORD            ; Variables for polygon-drawing
  111. VAR     x1,             WORD
  112. VAR     y1,             WORD
  113. VAR     x2,             WORD
  114. VAR     y2,             WORD
  115. VAR     x_increase,     WORD
  116. VAR     color,          BYTE
  117. VAR     pgon_min_y,     WORD
  118. VAR     pgon_max_y,     WORD
  119.  
  120. VAR     worm_x1,        BYTE            ; Variables for the worm
  121. VAR     worm_x2,        BYTE
  122. VAR     worm_x3,        BYTE
  123. VAR     worm_y,         BYTE
  124. VAR     worm_lenght,    BYTE
  125.  
  126.  
  127. ; Code ====================================================
  128.  
  129. CODESEG
  130. STARTUPCODE
  131.     
  132.  
  133. ; Initialize everything -----------------------------------
  134.  
  135. type_message:
  136.     
  137.     VAR_INITIALIZE                  ; Initialize & allocate variables
  138.  
  139.     MOV     AX,CS                   ; Make sure SREGs are correct
  140.     MOV     DS,AX
  141.     MOV     ES,AX
  142.  
  143.     CLD                             ; Just to be sure
  144.  
  145.     MOV     AX,CS                   ; Calculate and store segments
  146.     MOV     codesegment,AX
  147.     ADD     AX,1001h
  148.     MOV     virtualscr,AX
  149.     ADD     AX,1001h
  150.     MOV     firestartscr,AX
  151.  
  152.     CALL    init_palettes           ; Initialize palettes
  153.     
  154.     MOV     fade_in_progress,1      ; Fade all colors to black
  155.     MOV     fade_source,OFFSET black_palette
  156.  
  157. init_fadeout:
  158.     CALL    vert_retrace            ; Wait for an retrace before
  159.     CALL    fade_palette            ; setting new palette
  160.  
  161.     CMP     fade_in_progress,1
  162.     JE      init_fadeout
  163.  
  164.     MOV     AX,13h                  ; Set VGA mode 13h
  165.     INT     10h
  166.  
  167.     CALL    get_fonts               ; Get CGA & VGA fonts
  168.     
  169.     CALL    create_sincos_table     ; Create full sincos-table
  170.  
  171.     CALL    init_virtual            ; Initialize virtual screen
  172.     
  173.     CALL    init_pgtable            ; Initialize table for polygons
  174.     
  175.     CALL    init_starfield          ; Initialize starfield
  176.     
  177.     MOV     dot_curr_char,OFFSET dot_text  ; Start dot-scroll from here
  178.  
  179.     MOV     count,30                ; Wait for the screen to settle down        
  180.     
  181. screen_wait:
  182.     CALL    vert_retrace
  183.  
  184.     DEC     count
  185.     JNZ     screen_wait
  186.  
  187.  
  188. ; Part 1: Ball-vectors ------------------------------------
  189.  
  190.     MOV     fade_in_progress,1      ; Fade in
  191.     MOV     fade_source,OFFSET palette
  192.  
  193.     MOV     morph_source,OFFSET ball_objects + 84
  194.  
  195.     MOV     sin_start_char,OFFSET sintext_balls  ; Sinus-scroll start
  196.     
  197.     CALL    handle_sinus            ; Show sinus-scroll
  198.  
  199. ball_loop:
  200.     CALL    draw_background         ; Redraw backround (erase balls)
  201.     
  202.     CALL    starfield               ; Draw stars
  203.     
  204.     CMP     morph_source,OFFSET ball_objects + 84*5
  205.     JB      ball_no_end_slide       ; Is the object '95'?
  206.     
  207.     CMP     timer,300               ; Is it time for sliding?
  208.     JB      ball_no_end_slide
  209.     
  210.     SUB     center_x,2              ; Slide object to the left
  211.  
  212.     CMP     center_x,-100           ; Time for the next part?
  213.     JL      part_2
  214.  
  215. ball_no_end_slide:
  216.     CMP     morph_source,OFFSET ball_objects
  217.     JB      ball_no_start_slide     ; Is the object 'circle'?
  218.     
  219.     CMP     center_x,154            ; Is the object in the center of the
  220.     JB      ball_no_start_slide     ; screen?
  221.     
  222.     SUB     center_x,2              ; No -> Slide object to the left
  223.  
  224. ball_no_start_slide:
  225.     CALL    morph_balls             ; Morph ball-objects
  226.     
  227.     CALL    calc_matrix             ; Calculate 3D-matrix
  228.  
  229.     MOV     SI,OFFSET ball_objects
  230.     MOV     count,28
  231.     CALL    rotate_all              ; Rotate all balls
  232.  
  233.     MOV     SI,OFFSET screen_coords
  234.     MOV     CX,28
  235.     CALL    sort_coords             ; Sort balls by distance
  236.     
  237.     CALL    draw_balls              ; Draw balls & shadows
  238.     
  239.     CALL    dot_scroll              ; Update dot-scroll
  240.  
  241.     CALL    vert_retrace            ; Wait for an vertical retrace
  242.     
  243.     CALL    flip_screen             ; Show virtual screen
  244.     
  245.     INC     x_rotation              ; Rotate object
  246.     INC     y_rotation
  247.     ADD     z_rotation,2
  248.  
  249.     MOVZX   CX,x_rotation           ; Rotate some more (break the pattern)
  250.     BT      CX,7
  251.     ADC     y_rotation,0
  252.  
  253.     MOV     AH,1                    ; Check for a key
  254.     INT     16h
  255.     JZ      ball_loop               ; No key pressed -> Keep looping
  256.  
  257.     MOV     AH,0                    ; Get the keypress from buffer
  258.     INT     16h
  259.  
  260.     CMP     AL,27                   ; ESC exits
  261.     JE      exit2dos
  262.  
  263.     CMP     AL,' '                  ; Space skips this part
  264.     JNE     ball_loop
  265.  
  266.  
  267. ; Part 2: Filled vectors ----------------------------------
  268.  
  269. part_2:
  270.     MOV     center_x,160            ; Slide to left from here
  271.     
  272.     MOV     x_rotation,215          ; Change viewpoint
  273.     MOV     y_rotation,128
  274.  
  275.     MOV     distance,310000h        ; Move object closer
  276.     
  277.     MOV     sin_start_char,OFFSET sintext_fvectors  ; Sinus-scroll start
  278.     
  279.     CALL    handle_sinus
  280.  
  281.     MOV     timer,0                 ; Reset timer
  282.  
  283. fvectors_loop:
  284.     INC     timer                   ; Advance timer
  285.  
  286.     CMP     timer,100               ; Morph from dot to stick?
  287.     JB      morph_to_stick
  288.     
  289.     CMP     timer,600               ; Morph from stick to flag?
  290.     JB      morph_to_flag
  291.  
  292.     CMP     timer,1200              ; From flag to map?
  293.     JB      morph_to_map
  294.     
  295.     CMP     timer,1470              ; From map to dot?
  296.     JB      morph_to_dot
  297.     
  298.     JMP     part_3                  ; Jump to the next part
  299.  
  300.  
  301. fvectors_back_here:
  302.     CALL    draw_background         ; Redraw backround (erase balls)
  303.     
  304.     CALL    starfield               ; Draw starfield
  305.     
  306.     CALL    calc_matrix             ; Calculate 3D-matrix
  307.  
  308.     MOV     SI,OFFSET vector_start
  309.     MOV     count,31
  310.     CALL    rotate_all              ; Rotate all points
  311.  
  312.     MOV     SI,OFFSET screen_coords ; Draw bottom half
  313.     MOV     count,8
  314.     MOV     color,15
  315.     CALL    draw_polygon
  316.     
  317.     MOV     count,6                 ; Draw upper half
  318.     MOV     color,15
  319.     CALL    draw_polygon
  320.     
  321.     MOV     count,5                 ; Draw 'head'
  322.     MOV     color,15
  323.     CALL    draw_polygon
  324.     
  325.     MOV     count,4                 ; Draw 'arm'
  326.     MOV     color,15
  327.     CALL    draw_polygon
  328.     
  329.     MOV     count,4                 ; Draw part of the arrow
  330.     MOV     color,95
  331.     CALL    draw_polygon
  332.     
  333.     MOV     count,4                 ; Draw part of the arrow
  334.     MOV     color,95
  335.     CALL    draw_polygon
  336.     
  337.     
  338.     CALL    dot_scroll              ; Update dot-scroll
  339.  
  340.     CALL    vert_retrace            ; Wait for an vertical retrace
  341.     
  342.     CALL    flip_screen             ; Show virtual screen
  343.     
  344.     INC     z_rotation              ; Rotate viewpoint
  345.  
  346.     MOV     AH,1                    ; Check for a key
  347.     INT     16h
  348.     JZ      fvectors_loop           ; No key pressed -> Keep looping
  349.  
  350.     MOV     AH,0                    ; Get the keypress from buffer
  351.     INT     16h
  352.  
  353.     CMP     AL,27                   ; ESC exits
  354.     JE      exit2dos
  355.  
  356.     CMP     AL,' '                  ; Space skips this part
  357.     JNE     fvectors_loop
  358.  
  359.  
  360. ; Part 3: Wormie ------------------------------------------
  361.  
  362. part_3:
  363.     MOV     sin_start_char,OFFSET sintext_wormie  ; Sinus-scroll start
  364.     
  365.     CALL    handle_sinus            ; Handle sinus-scroll
  366.  
  367.     MOV     worm_lenght,1           ; Starting lenght
  368.     MOV     center_x,154            ; Center of the object on screen
  369.  
  370.     MOV     timer,0                 ; Reset timer
  371.  
  372. wormie_loop:
  373.     INC     timer                   ; Advance timer
  374.  
  375.     CMP     timer,1800              ; Time to slide to the left?
  376.     JB      wormie_maxsize
  377.     
  378.     SUB     center_x,2              ; Yes -> Slide wormie
  379.  
  380.     CMP     center_x,-140           ; Time for the next part?
  381.     JL      part_4
  382.  
  383. wormie_maxsize:        
  384.     CMP     worm_lenght,250         ; Has the worm reached it's max size?
  385.     JE      wormie_cont             ; Yes -> Continue
  386.  
  387.     CMP     power_meter,500         ; Do we have enough CPU-power?
  388.     JB      wormie_cont             ; No -> Don't grow
  389.  
  390.     MOV     AX,timer                ; Does the worm need to grow?
  391.     TEST    AX,3
  392.     JNZ     wormie_cont
  393.  
  394.     INC     worm_lenght             ; Yes
  395.  
  396. wormie_cont:
  397.     CALL    draw_background         ; Redraw backround (erase balls)
  398.     
  399.     CALL    starfield               ; Draw stars
  400.     
  401.     CALL    draw_wormie             ; Draw worm
  402.     
  403.     CALL    dot_scroll              ; Update dot-scroll
  404.  
  405.     CALL    vert_retrace            ; Wait for an vertical retrace
  406.     
  407.     CALL    flip_screen             ; Show virtual screen
  408.     
  409.     MOV     AH,1                    ; Check for a key
  410.     INT     16h
  411.     JZ      wormie_loop             ; No key pressed -> Keep looping
  412.  
  413.     MOV     AH,0                    ; Get the keypress from buffer
  414.     INT     16h
  415.  
  416.     CMP     AL,27                   ; ESC exits
  417.     JE      exit2dos
  418.  
  419.     CMP     AL,' '                  ; Space skips this part
  420.     JNE     wormie_loop
  421.  
  422.  
  423. ; Part 4: The End -----------------------------------------
  424.  
  425. part_4:
  426.     MOV     fade_in_progress,1      ; Fade all colors to black
  427.     MOV     fade_source,OFFSET black_palette
  428.  
  429.     MOV     count,100
  430.  
  431. part4_fadeout:
  432.     CALL    dot_scroll              ; Update dot-scroll
  433.  
  434.     CALL    vert_retrace            ; Wait for an retrace before
  435.     CALL    fade_palette            ; setting new palette
  436.  
  437.     CALL    flip_screen             ; Show virtualscreen
  438.     
  439.     DEC     count                   ; Loop
  440.     JNZ     part4_fadeout
  441.     
  442.     CALL    handle_fire             ; Show burning text
  443.     
  444.     JMP     exit2dos_no_fade        ; Exit
  445.  
  446.  
  447. ; Handle sinus-scroll -------------------------------------
  448.  
  449. handle_sinus:
  450.     CALL    draw_background         ; Redraw backround (erase everything)
  451.     
  452.     CALL    starfield               ; Draw starfield
  453.     
  454.     CALL    sinus_scroll            ; Update sinus-scroll
  455.     
  456.     CALL    dot_scroll              ; Update dot-scroll
  457.  
  458.     CALL    vert_retrace            ; Wait for an vertical retrace
  459.     
  460.     CALL    fade_palette            ; Fade palette (if needed)
  461.     
  462.     CALL    flip_screen             ; Show virtual screen
  463.     
  464.     MOV     SI,sin_start_char       ; Get current sinus-scroll char
  465.     MOV     AL,[SI]
  466.     
  467.     CMP     AL,0                    ; Is it 0?
  468.     JNE     _handle_sinus_cont      ; No -> Keep scrollin'
  469.     
  470.     INC     sin_start_char          ; Yes -> Skip over the 0
  471.     
  472.     RET                             ; Quit
  473.     
  474. _handle_sinus_cont:
  475.     MOV     AH,1                    ; Check for a key
  476.     INT     16h
  477.     JZ      handle_sinus            ; No key pressed -> Keep looping
  478.  
  479.     MOV     AH,0                    ; Get the keypress from buffer
  480.     INT     16h
  481.  
  482.     CMP     AL,27                   ; ESC exits
  483.     JE      exit2dos
  484.  
  485.     CMP     AL,' '                  ; Space skips this part
  486.     JNE     handle_sinus
  487.  
  488.     RET
  489.  
  490.  
  491. ; Cleanup and exit ----------------------------------------
  492.  
  493. exit2dos:
  494.  
  495.     MOV     fade_in_progress,1      ; Fade all colors to black
  496.     MOV     fade_source,OFFSET black_palette
  497.  
  498. exit_fadeout:
  499.     CALL    vert_retrace            ; Wait for an retrace before
  500.     CALL    fade_palette            ; setting new palette
  501.  
  502.     CMP     fade_in_progress,1
  503.     JE      exit_fadeout
  504.  
  505. exit2dos_no_fade:
  506.     MOV     AX,3                    ; Set normal textmode
  507.     INT     10h
  508.  
  509.     MOV     count,30                ; Wait for the screen to settle down        
  510.     
  511. exit_wait:
  512.     CALL    vert_retrace
  513.  
  514.     DEC     count
  515.     JNZ     exit_wait
  516.  
  517.     MOV     AX,1301h                ; Print exitstring
  518.     MOV     BX,30
  519.     MOV     CX,OFFSET end_text_end - end_text
  520.     MOV     DX,0101h
  521.     MOV     BP,OFFSET end_text
  522.     INT     10h
  523.     
  524.     VAR_DEALLOCATE                  ; Deallocate variables
  525.  
  526.     MOV     AX,4C00h                ; Exit 2 DOS
  527.     INT     21h
  528.  
  529.  
  530. ; Initalization ===========================================
  531.  
  532. ; Get CGA 8*8 & VGA 8*16 fonts ----------------------------
  533.  
  534. PROC get_fonts
  535.     
  536.     PUSH    BP
  537.  
  538.     MOV     AX,1130h                ; Get pointer to the CGA 8*8 font
  539.     MOV     BH,3
  540.     INT     10h
  541.  
  542.     MOV     AX,ES                   ; ES:BP -> DS:SI = Source adress
  543.     MOV     DS,AX
  544.     MOV     SI,BP
  545.  
  546.     POP     BP
  547.     
  548.     MOV     ES,codesegment          ; ES:DI = Destination adress
  549.     MOV     DI,OFFSET cga_font
  550.  
  551.     MOV     CX,512                  ; Copy 512 WORDs (128 characters)
  552.  
  553.     REP MOVSW                       ; Copy font
  554.  
  555.     PUSH    BP
  556.  
  557.     MOV     AX,1130h                ; Get pointer to the VGA 8*16 font
  558.     MOV     BH,6
  559.     INT     10h
  560.  
  561.     MOV     AX,ES                   ; ES:BP -> DS:SI = Source adress
  562.     MOV     DS,AX
  563.     MOV     SI,BP
  564.  
  565.     POP     BP
  566.     
  567.     MOV     ES,codesegment          ; ES:DI = Destination adress
  568.     MOV     DI,OFFSET vga_font
  569.  
  570.     MOV     CX,1024                 ; Copy 128 characters
  571.  
  572.     REP MOVSW                       ; Copy font
  573.  
  574.     MOV     DS,codesegment          ; Restore regs
  575.  
  576.     RET
  577.  
  578. ENDP
  579.  
  580.  
  581. ; Create full sincos-table --------------------------------
  582.  
  583. PROC create_sincos_table
  584.  
  585.     MOV     SI,OFFSET partial_sincos ; Copy first quadrant of the table
  586.     MOV     DI,OFFSET sincos_table
  587.     MOV     CX,65
  588.  
  589.     REP MOVSW
  590.  
  591.     MOV     SI,OFFSET sincos_table + 126
  592.  
  593. _create_sct_2nd:
  594.     MOV     AX,[SI]                 ; 2nd quadrant is the same as the
  595.     MOV     [DI],AX                 ; first reversed
  596.  
  597.     DEC     SI
  598.     DEC     SI
  599.     INC     DI
  600.     INC     DI
  601.  
  602.     CMP     SI,OFFSET sincos_table
  603.     JA      _create_sct_2nd
  604.  
  605. _create_sct_3rd_4th:
  606.     MOVSW                           ; 3rd & 4th quadrants are the same as
  607.     NEG     [WORD DI-2]             ; the 1st & 2nd, only negative
  608.  
  609.     CMP     SI,OFFSET sincos_table + 256
  610.     JB      _create_sct_3rd_4th
  611.  
  612.     RET
  613.  
  614. ENDP
  615.  
  616.  
  617. ; Initialize palettes -------------------------------------
  618.  
  619. PROC init_palettes
  620.  
  621.     CALL    vert_retrace            ; Must do before reading the palette
  622.     
  623.     MOV     AX,1017h                ; Read current palette
  624.     MOV     BX,0
  625.     MOV     CX,96
  626.     MOV     DX,OFFSET vga_palette
  627.     INT     10h
  628.  
  629.     MOV     DI,OFFSET black_palette ; Create all black palette
  630.     XOR     AX,AX                   ; and stuff
  631.     MOV     CX,244
  632.  
  633.     REP STOSW
  634.  
  635.     MOV     DI,OFFSET palette       ; Create slide of greys
  636.     MOV     CX,16                   ; 16 colors
  637.     XOR     AX,AX
  638.  
  639. _init_pal_grey:
  640.     STOSW                           ; Store 3 bytes (RGB)
  641.     STOSB
  642.     
  643.     ADD     AX,0404h                ; Advance RGB-values
  644.  
  645.     LOOP    _init_pal_grey
  646.  
  647.     MOV     SI,OFFSET colors        ; Copy fixed colors
  648.     MOV     CX,24
  649.  
  650.     REP MOVSW
  651.  
  652.     MOV     AL,0                    ; Create slide of blues
  653.  
  654. _init_pal_blue:
  655.     MOV     [WORD DI],0             ; Red & green are zeros
  656.     MOV     [DI+2],AL               ; Blue
  657.  
  658.     INC     AL                      ; Next blue is little lighter
  659.     ADD     DI,3                    ; Increase pointer
  660.  
  661.     CMP     DI,OFFSET palette+288   ; Done?
  662.     JB      _init_pal_blue
  663.  
  664.     RET
  665.  
  666. ENDP
  667.  
  668.  
  669. ; Initialize palette for the fire -------------------------
  670.  
  671. PROC init_fire_palette
  672.  
  673.     XOR     AX,AX                   ; Create colors for the fire
  674.     MOV     BL,00
  675.  
  676.     MOV     DI,OFFSET palette       ; Starting offset of the palette
  677.     
  678.     MOV     count,0                 ; Reset counter
  679.  
  680. _init_pal_fire:
  681.     INC     count                   ; Increase counter
  682.     
  683.     MOV     [DI],AX                 ; Store RGB
  684.     MOV     [DI+2],BL
  685.     
  686.     ADD     DI,3                    ; Advance pointer
  687.     
  688.     CMP     count,31                ; Do we have enough reds?
  689.     JA      _init_pal_fire_yellow
  690.     
  691.     ADD     AL,2                    ; No -> Increase red
  692.  
  693.     JMP     _init_pal_fire          ; Loop
  694.  
  695. _init_pal_fire_yellow:
  696.     CMP     count,62                ; Do we have enough yellows?
  697.     JA      _init_pal_fire_white
  698.  
  699.     ADD     AH,2                    ; No -> Increase green
  700.  
  701.     JMP     _init_pal_fire          ; Loop
  702.  
  703. _init_pal_fire_white:
  704.     CMP     count,93                ; Do we have enough whites?
  705.     JA      _init_pal_fire_end
  706.     
  707.     ADD     BL,2                    ; No -> Increase blue
  708.     
  709.     JMP     _init_pal_fire          ; Loop
  710.  
  711. _init_pal_fire_end:
  712.     MOV     [DWORD DI],3F3F3F3Fh    ; Store last 2 colors
  713.     MOV     [WORD DI+4],3F3Fh
  714.     
  715.     RET
  716.  
  717. ENDP
  718.  
  719.  
  720. ; Initialize virtual screen -------------------------------
  721.     
  722. PROC init_virtual
  723.  
  724.     CALL    draw_background         ; Draw background
  725.     
  726.     MOV     ES,virtualscr           ; Draw here
  727.     MOV     DI,58240                ; Starting offset
  728.  
  729.     XOR     AX,AX                   ; Draw 3 black lines
  730.     MOV     CX,240
  731.  
  732.     REP STOSD
  733.  
  734.     MOV     count,8                 ; Dot-scroll has 8 rows
  735.  
  736. _init_virt_dot:        
  737.     MOV     AX,0018h                ; One black and one green dot
  738.     MOV     CX,160                  ; Draw one line
  739.  
  740.     REP STOSW
  741.  
  742.     XOR     AX,AX                   ; Draw one black line
  743.     MOV     CX,160
  744.  
  745.     REP STOSW
  746.  
  747.     DEC     count                   ; Done?
  748.     JNZ     _init_virt_dot
  749.  
  750.     MOV     ES,codesegment          ; Restore ES
  751.     
  752.     RET
  753.  
  754. ENDP
  755.  
  756.  
  757. ; Initialize table for polygon-drawing --------------------
  758.  
  759. PROC init_pgtable
  760.  
  761.     MOV     DI,OFFSET pg_table      ; Fill the table with 8000h
  762.     MOV     CX,200
  763.     MOV     AX,8000h
  764.  
  765.     REP STOSW
  766.  
  767.     RET
  768.  
  769. ENDP
  770.  
  771.  
  772. ; Initialize starfield ------------------------------------
  773.  
  774. PROC init_starfield
  775.  
  776.     MOV     DI,OFFSET starfield_data ; Stardata offset
  777.     MOV     SI,100h                 ; Source for random numbers
  778.     XOR     BX,BX                   ; First star's offset
  779.     MOV     CX,100                  ; Create 200 stars
  780.  
  781. _init_stars_loop:
  782.     XOR     AX,AX
  783.     
  784.     LODSB                           ; Get random number
  785.     ADD     AX,270
  786.     
  787.     ADD     BX,AX                   ; Advance pointer
  788.  
  789.     MOV     AX,BX                   ; Store pointer
  790.     STOSW
  791.  
  792.     ROR     AL,4
  793.     STOSB                           ; Store color
  794.     
  795.     LOOP    _init_stars_loop
  796.  
  797.     RET
  798.  
  799. ENDP
  800.  
  801.  
  802. ; Color routines ==========================================
  803.  
  804. ; Set palette ---------------------------------------------
  805.  
  806. PROC set_palette
  807.  
  808.     MOV     DX,3C8h                 ; Start from color 0
  809.     XOR     AL,AL
  810.     OUT     DX,AL
  811.  
  812.     INC     DX                      ; Output to port 3C9
  813.     MOV     CX,288                  ; Set 288 registers (96 colors)
  814.     MOV     SI,OFFSET vga_palette   ; Offset of the palette
  815.  
  816.     REP OUTSB                       ; Set DACs
  817.  
  818.     RET
  819.  
  820. ENDP
  821.  
  822.  
  823. ; Fade palette --------------------------------------------
  824.  
  825. PROC fade_palette
  826.  
  827.     CMP     fade_in_progress,0      ; Do we have to do it?
  828.     JE      _fade_pal_end
  829.  
  830.     MOV     SI,fade_source          ; Destination palette
  831.     MOV     DI,OFFSET vga_palette   ; Current palette
  832.     MOV     CX,288
  833.     CALL    morph                   ; Morph (fade) palette
  834.  
  835.     CMP     AX,0                    ; Are we through with the fading?
  836.     JE      _fade_pal_set
  837.  
  838.     MOV     fade_in_progress,0      ; Yep
  839.  
  840. _fade_pal_set:        
  841.     CALL    set_palette             ; Set new palette
  842.  
  843. _fade_pal_end:
  844.     RET
  845.  
  846. ENDP
  847.  
  848.  
  849. ; Scroll routines =========================================
  850.  
  851. ; Update dot-scroll on the bottom of the screen -----------
  852.  
  853. PROC dot_scroll
  854.  
  855.     CALL    dot_2left               ; Scroll to the left
  856.  
  857.     MOV     ES,virtualscr           ; Scroll here
  858.  
  859.     DEC     dot_horiz_place         ; Are we through with the last char?
  860.     JNS     _dot_still_the_same
  861.  
  862.     INC     dot_curr_char           ; Yep -> Next char from the string
  863.     MOV     dot_horiz_place,7
  864.  
  865. _dot_still_the_same:
  866.     MOV     SI,dot_curr_char        ; Get current char
  867.     MOVZX   BX,[SI]
  868.  
  869.     CMP     BL,0                    ; Is it 0?
  870.     JNE     _dot_char_not_0         ; Nope -> Continue
  871.  
  872.     MOV     dot_curr_char,OFFSET dot_text ; Yes -> Reset charptr
  873.     
  874. _dot_char_not_0:
  875.     SHL     BX,3                    ; Every char takes 8 bytes
  876.     ADD     BX,OFFSET cga_font      ; BX = Ptr to the char in font
  877.  
  878.     MOV     DI,0E87Eh               ; Start drawing from here
  879.     MOVZX   DX,dot_horiz_place      ; Draw this column from the char
  880.  
  881. _dot_loop:
  882.     XOR     AL,AL
  883.     BT      [BX],DX                 ; Get one bit from the font
  884.     ADC     AL,24                   ; Calculate color
  885.     INC     BX
  886.  
  887.     MOV     [ES:DI],AL              ; Draw
  888.  
  889.     ADD     DI,640                  ; Next row (2 rows down actually)
  890.  
  891.     CMP     DI,64000                ; Loop through all rows
  892.     JB      _dot_loop
  893.  
  894.     MOV     ES,codesegment          ; Restore ES
  895.     
  896.     RET
  897.     
  898. ENDP
  899.  
  900.  
  901. ; Scroll dot-scroll to the left ---------------------------
  902.  
  903. PROC dot_2left
  904.  
  905.     MOV     AX,virtualscr           ; Adress of the video memory 
  906.     MOV     DS,AX
  907.     MOV     ES,AX
  908.  
  909.     MOV     SI,0E742h               ; Copy from
  910.     MOV     DI,0E740h               ; Copy to
  911.  
  912. _dot_2left_loop:        
  913.     MOV     CX,159                  ; One line = 159 WORDs
  914.  
  915.     REP MOVSW                       ; Scroll one line
  916.  
  917.     ADD     SI,322                  ; SI & DI 2 rows down
  918.     ADD     DI,322
  919.     
  920.     CMP     DI,64000                ; All lines scrolled?
  921.     JB      _dot_2left_loop
  922.  
  923.     MOV     AX,CS                   ; Restore DS & ES
  924.     MOV     DS,AX
  925.     MOV     ES,AX
  926.  
  927.     RET
  928.  
  929. ENDP
  930.  
  931.  
  932. ; Update sinus-scroll -------------------------------------
  933.  
  934. PROC sinus_scroll
  935.  
  936.     MOV     ES,virtualscr           ; Draw here
  937.     
  938.     ADD     sin_sinptr,4            ; Move sinus-effect
  939.  
  940.     DEC     sin_horiz_start         ; Scroll to the left
  941.     JNS     _sin_same_start_char    ; Next starting char?
  942.  
  943.     INC     sin_start_char          ; Yep -> Next char from the string
  944.     MOV     sin_horiz_start,7
  945.  
  946. _sin_same_start_char:
  947.     MOV     AX,sin_start_char       ; Startptr to text
  948.     MOV     sin_curr_char,AX
  949.     
  950.     MOV     AL,sin_sinptr           ; Pointer to sinetable
  951.     
  952.     XOR     BX,BX                   ; Starting x-coordinate
  953.     MOVZX   DI,sin_horiz_start      ; Horizontal position inside char
  954.  
  955. _sin_loop:
  956.     MOVZX   SI,AL                   ; Get SIN(angle)
  957.     SHL     SI,1                    ; Table contains WORDs
  958.     MOV     DX,[WORD SI+sincos_table] ; Get sine
  959.  
  960.     INC     AL                      ; Increase sine-pointer
  961.     
  962.     SAR     DX,9                    ; Calculate y-coordinate
  963.     ADD     DX,80
  964.  
  965.     MOV     SI,sin_curr_char        ; SI=Pointer to char in font
  966.     MOVZX   SI,[SI]
  967.     SHL     SI,4
  968.     ADD     SI,OFFSET vga_font
  969.     
  970.     MOV     CX,15                   ; Loop through 16 rows
  971.  
  972. _sin_column_loop:
  973.     BT      [SI],DI                 ; Get one bit from the font
  974.     JNC     _sin_column_nodraw      ; Bit was 0 -> Don't draw
  975.  
  976.     PUSHA
  977.  
  978.     ADD     BH,DL                   ; Address = (y * 320) + x
  979.     SHL     DX,6
  980.     ADD     BX,DX
  981.  
  982.     MOV     SI,OFFSET sinus_colors
  983.     ADD     SI,CX        
  984.     
  985.     MOV     AL,[SI]
  986.     MOV     AH,AL
  987.  
  988.     MOV     [WORD ES:BX],AX         ; Draw 2 points
  989.  
  990.     POPA                            ; Funny, but must be here!
  991.     PUSHA
  992.  
  993.     SUB     DX,80                   ; Calculate y-coordinate for shadow
  994.     SAR     DX,2
  995.     ADD     DX,155
  996.  
  997.     ADD     BH,DL                   ; Address = (y * 320) + x
  998.     SHL     DX,6
  999.     ADD     BX,DX
  1000.  
  1001.     MOV     [WORD ES:BX],1A1Ah      ; Draw 2 points of shadow
  1002.  
  1003.     POPA
  1004.  
  1005. _sin_column_nodraw:
  1006.     INC     DX                      ; Increase y-coordinate
  1007.     INC     SI                      ; Next row in the font
  1008.  
  1009.     LOOP    _sin_column_loop        ; Loop through all rows
  1010.  
  1011.     DEC     DI                      ; Next column
  1012.     JNS     _sin_char_not_finished  ; This char drawed?
  1013.  
  1014.     INC     sin_curr_char           ; Yes -> Next char
  1015.     
  1016.     MOV     DI,7
  1017.  
  1018. _sin_char_not_finished:
  1019.     ADD     BX,2                    ; Increase x-coordinate
  1020.  
  1021.     CMP     BX,320                  ; All columns drawed
  1022.     JNE     _sin_loop
  1023.  
  1024.     MOV     ES,codesegment
  1025.     
  1026.     RET
  1027.  
  1028. ENDP
  1029.  
  1030.  
  1031. ; Graphic routines ========================================
  1032.  
  1033. ; Wait for the next vertical retrace ----------------------
  1034.  
  1035. PROC vert_retrace
  1036.     
  1037.     MOV     power_meter,0           ; Zero out our counter
  1038.     
  1039.     MOV     DX,3DAh                 ; Use port 3D4
  1040.  
  1041. _vert_retrace_off:
  1042.     IN      AL,DX                   ; Get vertical retrace state
  1043.     
  1044.     TEST    AL,08h
  1045.     JNZ     _vert_retrace_off       ; Loop until it's off
  1046.  
  1047. _vert_retrace_on:
  1048.     INC     power_meter             ; Increase counter
  1049.     
  1050.     IN      AL,DX                   ; Get vertical retrace state
  1051.     
  1052.     TEST    AL,08h
  1053.     JZ      _vert_retrace_on        ; Loop until it's on
  1054.  
  1055.     RET
  1056.  
  1057. ENDP
  1058.  
  1059.  
  1060. ; Draw sprite ---------------------------------------------
  1061.  
  1062. ; BX - Sprite number
  1063. ; CX - X-coordinate
  1064. ; DX - Y-coordinate
  1065.  
  1066. PROC putsprite
  1067.  
  1068.     CMP     CX,305                  ; Check x-limits
  1069.     JA      _ps_end
  1070.  
  1071.     MOV     ES,virtualscr           ; Draw to virtual screen
  1072.     
  1073.     INC     BX
  1074.     SHL     BX,1                    ; Start of the sprite to SI
  1075.     MOV     SI,[BX+OFFSET sprites]
  1076.     ADD     SI,OFFSET sprites
  1077.  
  1078.     MOVZX   AX,[SI]                 ; Get width
  1079.  
  1080.     ADD     CH,DL                   ; Count destination adress
  1081.     SHL     DX,6
  1082.     ADD     CX,DX
  1083.     MOV     DI,CX
  1084.  
  1085.     MOV     DX,320                  ; DX = 320-width
  1086.     SUB     DX,AX
  1087.  
  1088.     ADD     AX,DI                   ; End of the first line
  1089.  
  1090.     MOV     BL,[SI+1]               ; Height = Lines to draw
  1091.     ADD     SI,2
  1092.  
  1093.     XOR     CH,CH                   ; We need this for BYTE -> WORD
  1094.  
  1095. _ps_loop:
  1096.     MOV     CL,[SI]                 ; Jump over the invicible area
  1097.     ADD     DI,CX
  1098.     MOV     CL,[SI+1]               ; Number of visible points
  1099.     ADD     SI,2
  1100.  
  1101.     SHR     CL,1                    ; Draw using WORDs
  1102.  
  1103.     REP MOVSW                       ; Draw
  1104.  
  1105.     JNC     _ps_even                ; Still one to draw?
  1106.  
  1107.     MOVSB                           ; Yes -> Draw BYTE
  1108.  
  1109. _ps_even:
  1110.     CMP     DI,AX                   ; End of this line?
  1111.     JB      _ps_loop                ; No -> Keep drawing
  1112.  
  1113.     ADD     AX,320                  ; Yes -> Next line ends just below
  1114.     ADD     DI,DX                   ; DI to the start of the next line
  1115.  
  1116.     DEC     BL                      ; All of the lines drawed?
  1117.     JNZ     _ps_loop                ; No -> Loop
  1118.  
  1119.     MOV     ES,codesegment
  1120.     
  1121. _ps_end:
  1122.     RET
  1123.  
  1124. ENDP
  1125.  
  1126.  
  1127. ; Draw all balls ------------------------------------------
  1128.  
  1129. PROC draw_balls
  1130.  
  1131.     MOV     count,28                ; Number of shadows to draw
  1132.     MOV     SI,OFFSET screen_coords ; Source offset
  1133.  
  1134. _draw_balls_shadows:
  1135.     MOV     CX,[SI]                 ; Get x
  1136.     MOV     BX,[SI+4]               ; Get z
  1137.     SAR     BX,11                   ; Place of the shadow
  1138.     MOV     DX,155
  1139.     SUB     DX,BX
  1140.     MOV     BX,2                    ; Sprite number
  1141.  
  1142.     PUSH    SI
  1143.     CALL    putsprite               ; Draw shadow
  1144.     POP     SI
  1145.  
  1146.     ADD     SI,6                    ; Next shadow
  1147.     
  1148.     DEC     count                   ; Done?
  1149.     JA      _draw_balls_shadows
  1150.  
  1151.     MOV     count,28                ; Number of balls to draw
  1152.     MOV     SI,OFFSET screen_coords ; Source offset
  1153.  
  1154. _draw_balls_loop:
  1155.     MOV     CX,[SI]                 ; Get x
  1156.     MOV     DX,[SI+2]               ; Get y
  1157.     MOV     BX,[SI+4]               ; Get z
  1158.     SHR     BX,15                   ; Big or small ball?
  1159.     XOR     BX,1
  1160.  
  1161.     PUSH    SI
  1162.     CALL    putsprite               ; Draw ball
  1163.     POP     SI
  1164.     
  1165.     ADD     SI,6                    ; Next ball
  1166.     
  1167.     DEC     count                   ; Done?
  1168.     JA      _draw_balls_loop
  1169.  
  1170.     RET
  1171.  
  1172. ENDP
  1173.  
  1174.  
  1175. ; Flip virtual screen to VGA ------------------------------
  1176.  
  1177. PROC flip_screen
  1178.  
  1179.     MOV     DS,virtualscr           ; Source segment
  1180.     MOV     ES,vgasegment           ; Destination segment
  1181.     XOR     DI,DI                   ; Offsets
  1182.     XOR     SI,SI
  1183.     MOV     ECX,16000               ; Copy this many DWORDs
  1184.  
  1185.     REP MOVSD                       ; Copy
  1186.  
  1187.     MOV     DS,codesegment          ; Restore Sregs
  1188.     MOV     ES,codesegment
  1189.  
  1190.     RET
  1191.     
  1192. ENDP
  1193.  
  1194.  
  1195. ; Redraw background ---------------------------------------
  1196.  
  1197. PROC draw_background
  1198.  
  1199.     MOV     ES,virtualscr           ; Draw eveything here
  1200.     XOR     DI,DI                   ; Starting offset
  1201.     XOR     EAX,EAX                 ; Fill with color 0 (black)
  1202.     MOV     CX,9440                 ; FIll first lines
  1203.  
  1204.     REP STOSD
  1205.  
  1206.     MOV     count,64                ; Create slide of blues
  1207.     MOV     AX,2020h                ; Starting color
  1208.  
  1209. _init_bg_blue:
  1210.     MOV     CX,160                  ; Draw one line
  1211.  
  1212.     REP STOSW
  1213.  
  1214.     ADD     AX,0101h                ; Next color
  1215.  
  1216.     DEC     count                   ; Done?
  1217.     JNZ     _init_bg_blue
  1218.  
  1219.     MOV     ES,codesegment          ; Restore ES
  1220.     
  1221.     RET
  1222.  
  1223. ENDP
  1224.  
  1225.  
  1226. ; Plot one point ------------------------------------------
  1227.  
  1228. ; BX - X-coordinate
  1229. ; DX - Y-coordinate
  1230. ; AL - Color
  1231. ; ES - Segment to draw to
  1232.  
  1233. PROC plot
  1234.     
  1235.     CMP     BX,319                  ; Check x-limits
  1236.     JA      _plot_end
  1237.  
  1238.     CMP     DX,199                  ; Check y-limits
  1239.     JA      _plot_end
  1240.     
  1241.     ADD     BH,DL                   ; Address = (y * 320) + x
  1242.     SHL     DX,6
  1243.     ADD     BX,DX
  1244.  
  1245.     MOV     [ES:BX],AL              ; Draw
  1246.  
  1247. _plot_end:
  1248.     RET
  1249.  
  1250. ENDP
  1251.  
  1252.  
  1253. ; Draw horizontal line ------------------------------------
  1254.  
  1255. ; AL - color
  1256. ; BX - x1
  1257. ; CX - x2
  1258. ; DX - y
  1259. ; ES - Segment to draw to
  1260.  
  1261. PROC scanline
  1262.  
  1263.     CMP     DX,184                  ; Y-coordinate out of range?
  1264.     JA      _scanl_end              ; Yes - > Quit
  1265.  
  1266.     CMP     CX,BX
  1267.     JE      plot                    ; x1 = x2 -> Plot one point
  1268.     JG      _scanl_no_swap          ; x1 > x2?
  1269.  
  1270.     XCHG    CX,BX                   ; Yes -> Swap them
  1271.  
  1272. _scanl_no_swap:
  1273.     CMP     BX,0                    ; x1 < 0?
  1274.     JG      _scanl_x1_ok
  1275.  
  1276.     XOR     BX,BX                   ; Yes -> x1 = 0
  1277.  
  1278. _scanl_x1_ok:
  1279.     CMP     CX,320                  ; x2 > 320?
  1280.     JL      _scanl_x2_ok
  1281.  
  1282.     MOV     CX,320                  ; Yes -> x2 = 320
  1283.  
  1284. _scanl_x2_ok:
  1285.     CMP     BX,CX                   ; Out of the screen horizontally?
  1286.     JG      _scanl_end              ; Yes -> Quit
  1287.  
  1288.     SUB     CX,BX                   ; Calculate lenght
  1289.     INC     CX
  1290.  
  1291.     ADD     BH,DL                   ; DI=y*320+x1 (starting adress)
  1292.     SHL     DX,6
  1293.     ADD     BX,DX
  1294.     MOV     DI,BX
  1295.  
  1296.     MOV     AH,AL                   ; Fix color for WORD-size writes
  1297.  
  1298.     SHR     CX,1                    ; Draw as WORDs
  1299.  
  1300.     REP STOSW                       ; Draw line
  1301.  
  1302.     JNC     _scanl_end              ; Was the lenght even?
  1303.  
  1304.     STOSB                           ; No -> Draw the last pixel
  1305.  
  1306. _scanl_end:
  1307.     RET
  1308.  
  1309. ENDP
  1310.  
  1311.  
  1312. ; Draw polygon --------------------------------------------
  1313.  
  1314. ; color - Color
  1315. ; Coordinates are pushed to stack: 8000h,X1,Y1,X2,Y2,...,Xn,Yn(,returnadress)
  1316. ; (There _MUST_ be at least three pairs of coordinates!)
  1317.  
  1318. PROC polygon
  1319.  
  1320. ; This part gets the coordinates from the stack
  1321.     
  1322.     MOV     ES,virtualscr           ; Draw to virtual screen
  1323.     
  1324.     POP     retadress               ; Get returnadress
  1325.  
  1326.     MOV     pgon_min_y,199          ; Initialize min/max y-coordinate
  1327.     MOV     pgon_max_y,0
  1328.     
  1329.     POP     DX                      ; Get first pair of coordinates
  1330.     POP     CX
  1331.  
  1332.     CALL    _pgon_check_y           ; Check y for top/bottom
  1333.     
  1334.     MOV     x1,CX                   ; Save them for the last line:
  1335.     MOV     y1,DX                   ;  (Xn, Yn) - (X1, Y1)
  1336.  
  1337.     POP     y2                      ; Get next pair of coords
  1338.     POP     x2
  1339.  
  1340.     CALL    _pgline                 ; Draw the line
  1341.  
  1342. _polygon_loop:
  1343.     MOV     CX,x2                   ; The ending coords of the last line
  1344.     MOV     DX,y2                   ; are the starting coords of the next
  1345.  
  1346.     CALL    _pgon_check_y           ; Check y for top/bottom
  1347.     
  1348.     POP     y2                      ; Get next Y
  1349.     CMP     y2,8000h                ; End of the coords?
  1350.     JE      _polygon_end            ; Yes - > Quit
  1351.  
  1352.     POP     x2                      ; Get next X
  1353.  
  1354.     CALL    _pgline                 ; Draw the line
  1355.  
  1356.     JMP     _polygon_loop           ; Loop
  1357.  
  1358. _polygon_end:
  1359.     MOV     y2,DX                   ; Restore DX after POP
  1360.     MOV     CX,x1                   ; Get saved (X1, Y1)
  1361.     MOV     DX,y1
  1362.  
  1363.     CALL    _pgline                 ; Draw the last line
  1364.  
  1365.     MOV     ES,codesegment          ; Restore ES
  1366.     
  1367.     MOV     DI,pgon_min_y           ; Clear PG_TABLE between min & max
  1368.     SHL     DI,1                    ; y-coordinate
  1369.     ADD     DI,OFFSET pg_table
  1370.  
  1371.     MOV     CX,pgon_max_y        
  1372.     SUB     CX,pgon_min_y
  1373.     INC     CX
  1374.  
  1375.     MOV     AX,8000h
  1376.  
  1377.     REP STOSW
  1378.     
  1379.     PUSH    retadress               ; Restore returnadress
  1380.  
  1381.     RET                             ; Exit
  1382.  
  1383.  
  1384. ; This part draws the lines and fills the polygon
  1385. ; The line is drawed between (CX, DX) and (x2, y2)
  1386.  
  1387. _pgline:
  1388.     PUSH    x2                      ; Save (x2,y2)
  1389.     PUSH    y2
  1390.  
  1391.     CMP     DX,y2                   ; Is DX = y2?
  1392.     JNE     _pgl_no_horiz
  1393.  
  1394.     MOV     BX,x2                   ; Yes -> Draw horizontal line
  1395.     
  1396.     POP     EAX                     ; Dump saved (x2, y2)
  1397.     MOV     AL,color                ; Get color        
  1398.  
  1399.     JMP     scanline                ; Draw scanline
  1400.  
  1401. _pgl_no_horiz:
  1402.     JL      _pgl_no_swap            ; Is DX > y2?
  1403.  
  1404.     XCHG    x2,CX                   ; Yes -> Swap coordinates
  1405.     XCHG    y2,DX
  1406.  
  1407. _pgl_no_swap:
  1408.     MOV     SI,DX                   ; Save DX (IDIV destroys DX)
  1409.  
  1410.     MOV     AX,x2                   ; AX = x2-x1
  1411.     SUB     AX,CX
  1412.     MOV     BX,y2                   ; BX = y2-y1
  1413.     SUB     BX,DX
  1414.  
  1415.     CWD                             ; Convert AX -> DX:AX for IDIV
  1416.     SHL     AX,6                    ; Lower 6 bits are decimals
  1417.  
  1418.     IDIV    BX                      ; AX = (x2-x1)/(y2-y1)
  1419.     
  1420.     MOV     x_increase,AX           ; Save the result
  1421.  
  1422.     MOV     DX,SI                   ; Restore DX
  1423.  
  1424.     MOV     SI,CX                   ; Starting x-coordinate
  1425.     MOV     BX,CX
  1426.     SHL     SI,6                    ; Lower 6 bits are decimals
  1427.  
  1428.     MOV     AL,color                ; Get drawing color
  1429.  
  1430.     MOV     DI,DX                   ; Calculate index to the table
  1431.     SHL     DI,1
  1432.     ADD     DI,OFFSET pg_table
  1433.  
  1434.     ADD     SI,20h
  1435.  
  1436. _pgl_loop:
  1437.     MOV     CX,[DI]                 ; Get a value from the table
  1438.  
  1439.     CMP     CX,8000h                ; Do we have an value in there?
  1440.     JNE     _pgl_draw_scanline      ; Yes -> Draw one line
  1441.  
  1442.     MOV     [DI],BX                 ; No -> Store current x to the table
  1443.  
  1444.     JMP     _pgl_next_line          ; We don't wanna draw now
  1445.  
  1446. _pgl_draw_scanline:
  1447.     PUSHA                           ; Save regs
  1448.     
  1449.     CALL    scanline                ; Draw line
  1450.  
  1451.     POPA                            ; Restore regs
  1452.  
  1453. _pgl_next_line:
  1454.     ADD     SI,x_increase           ; Increase x-coordinate
  1455.     MOV     BX,SI                   ; Move it to BX (BX=integer part of x)
  1456.     SAR     BX,6                    ; Get rid of the decimals
  1457.     
  1458.     INC     DX                      ; Increase y-coordinate by 1
  1459.  
  1460.     ADD     DI,2
  1461.     
  1462.     CMP     DX,y2                   ; All lines drawed?
  1463.     JLE     _pgl_loop               ; No -> Keep drawing
  1464.  
  1465.     POP     y2                      ; Restore (x2, y2)
  1466.     POP     x2
  1467.  
  1468.     RET
  1469.  
  1470.  
  1471. ; This subroutine checks if given Y is the top/bottom y-coordinate
  1472.  
  1473. _pgon_check_y:
  1474.     CMP     DX,pgon_min_y           ; Y greater than top coordinate?
  1475.     JGE     _pgon_check_max_y       ; Yes -> Skip set
  1476.  
  1477.     MOV     pgon_min_y,DX           ; No -> Set new top
  1478.  
  1479. _pgon_check_max_y:
  1480.     CMP     DX,pgon_max_y           ; Y less than bottom coordinate?
  1481.     JLE     _pgon_check_y_end       ; Yes -> Skip set
  1482.  
  1483.     MOV     pgon_max_y,DX           ; Set new bottom coordinate
  1484.  
  1485. _pgon_check_y_end:
  1486.     RET
  1487.  
  1488.  
  1489. ENDP
  1490.  
  1491.  
  1492. ; Handle polygon-drawing ----------------------------------
  1493.  
  1494. ; count - Number of points in polygon
  1495. ; SI    - Pointer to coordinates
  1496. ; color - Color of the polygon
  1497.  
  1498. PROC draw_polygon
  1499.     
  1500.     MOV     temp,SI                 ; Save SI
  1501.     
  1502.     MOV     CL,count                ; Use CL as a counter
  1503.     
  1504.     PUSH    8000h                   ; Push coordinates to stack
  1505.  
  1506. _draw_polygon:
  1507.     PUSH    [WORD SI]               ; Push x
  1508.     PUSH    [WORD SI+2]             ; Push y
  1509.     
  1510.     ADD     SI,6                    ; Advance pointer
  1511.  
  1512.     DEC     CL                      ; Loop through all points
  1513.     JNZ     _draw_polygon
  1514.  
  1515.     CALL    polygon                 ; Draw polygon
  1516.  
  1517.     MOV     SI,temp                 ; Restore SI
  1518.     
  1519.  
  1520.     PUSH    8000h                   ; Push shadow's coords to stack
  1521.  
  1522.     MOV     color,26                ; Change color
  1523.  
  1524. _draw_pgon_shadow:
  1525.     PUSH    [WORD SI]               ; Push x
  1526.     
  1527.     MOV     BX,[SI+4]               ; Get z
  1528.     SAR     BX,11                   ; Place of the shadow
  1529.     MOV     DX,155
  1530.     SUB     DX,BX
  1531.  
  1532.     PUSH    DX                      ; Push y
  1533.     
  1534.     ADD     SI,6                    ; Advance pointer
  1535.  
  1536.     DEC     count                   ; Loop through all points
  1537.     JNZ     _draw_pgon_shadow
  1538.  
  1539.     MOV     temp,SI                 ; Save SI
  1540.     
  1541.     CALL    polygon                 ; Draw shadow
  1542.  
  1543.     MOV     SI,temp                 ; Restore SI
  1544.     
  1545.     RET
  1546.  
  1547. ENDP
  1548.  
  1549.  
  1550. ; Draw starfield ------------------------------------------
  1551.  
  1552. PROC starfield
  1553.  
  1554.     MOV     SI,OFFSET starfield_data ; Source offset
  1555.     MOV     CX,100                  ; Draw 200 stars
  1556.     MOV     ES,virtualscr           ; Draw here
  1557.     
  1558. _starf_loop:        
  1559.     LODSW                           ; Get offset of an star
  1560.  
  1561.     MOV     BX,AX
  1562.  
  1563.     ADD     [BYTE SI],2             ; Change color
  1564.  
  1565.     MOVZX   AX,[SI]                 ; Get color
  1566.     SHR     AL,3                    ; Divide it by 8 (0-255 -> 0-31)
  1567.  
  1568.     INC     SI                      ; Increase source pointer
  1569.  
  1570.     CMP     AL,15                   ; Colors 0-15 can be drawed right away
  1571.     JBE     _starf_draw
  1572.  
  1573.     MOV     DL,AL                   ; Colors 16-31 need some processing
  1574.     MOV     AL,31
  1575.     SUB     AL,DL
  1576.  
  1577. _starf_draw:
  1578.     MOV     [BYTE ES:BX],AL         ; Draw star
  1579.  
  1580.     LOOP    _starf_loop             ; Loop through all stars
  1581.  
  1582.     MOV     ES,codesegment          ; Restore ES
  1583.     
  1584.     RET
  1585.  
  1586. ENDP
  1587.  
  1588.  
  1589. ; Draw wormie ---------------------------------------------
  1590.  
  1591. PROC draw_wormie
  1592.  
  1593.     INC     worm_x1                 ; Wiggle worm
  1594.     ADD     worm_x2,2 
  1595.     INC     worm_x3
  1596.     
  1597.     INC     worm_y
  1598.  
  1599.     MOV     AL,worm_x1              ; Load worm_?? variables to registers
  1600.     MOV     AH,worm_x2
  1601.     MOV     BL,worm_x3
  1602.     MOV     BH,worm_y
  1603.     
  1604.     MOV     CL,worm_lenght          ; Init loop-counter
  1605.     MOV     count,CL
  1606.  
  1607. _dworm_loop:        
  1608.     MOVZX   SI,AL                   ; Modify x with first sine
  1609.     SHL     SI,1
  1610.     MOV     CX,[WORD SI+sincos_table] ; Get SIN(AL)
  1611.     
  1612.     SAR     CX,8                    ; Wiggle worm
  1613.     ADD     AL,2
  1614.     
  1615.     MOVZX   SI,AH                   ; Modify x with second sine
  1616.     SHL     SI,1
  1617.     MOV     DI,[WORD SI+sincos_table] ; Get SIN(AH)
  1618.     
  1619.     SAR     DI,9                    ; Wiggle
  1620.     ADD     CX,DI
  1621.     ADD     AH,9
  1622.  
  1623.     MOVZX   SI,BL                   ; Modify x with 3rd sine
  1624.     SHL     SI,1
  1625.     MOV     DI,[WORD SI+sincos_table] ; Get SIN(BL)
  1626.     
  1627.     SAR     DI,9                    ; Wiggle
  1628.     ADD     CX,DI
  1629.     ADD     BL,3
  1630.  
  1631.     MOVZX   SI,BH                   ; Modify y with sine
  1632.     SHL     SI,1
  1633.     MOV     DX,[WORD SI+sincos_table] ; Get SIN(BH)
  1634.     
  1635.     SAR     DX,8                    ; Wiggle
  1636.     ADD     BH,3
  1637.  
  1638.     ADD     CX,center_x             ; Move the worm to the center of the
  1639.     ADD     DX,center_y             ; screen
  1640.     
  1641.     PUSHA                           ; Putsprite destroys regs
  1642.     
  1643.     CALL    draw_worm_dot           ; Draw one dot
  1644.     
  1645.     POPA                            ; Restore regs
  1646.  
  1647.     DEC     count                   ; Loop through all dots
  1648.     JNZ     _dworm_loop
  1649.  
  1650.     RET
  1651.  
  1652. ENDP
  1653.  
  1654.  
  1655. ; Draw one dot for the wormie -----------------------------
  1656.  
  1657. ; CX - X-coordinate
  1658. ; DX - Y   -"-
  1659.  
  1660. PROC draw_worm_dot
  1661.  
  1662.     MOV     x1,CX                   ; Save (x,y) for the shadow
  1663.     MOV     y1,DX
  1664.     
  1665.     MOV     BX,3                    ; Draw sprite #3 (dot)
  1666.     CALL    putsprite
  1667.  
  1668.     MOV     CX,x1                   ; Restore (x,y)
  1669.     MOV     DX,y1
  1670.  
  1671.     SHR     DX,4                    ; Calculate the place of the shadow
  1672.     ADD     DX,155
  1673.     
  1674.     MOV     BX,2                    ; Draw sprite #2 (shadow)
  1675.     CALL    putsprite
  1676.  
  1677.     RET
  1678.  
  1679. ENDP
  1680.  
  1681.  
  1682. ; Draw burning text ---------------------------------------
  1683.  
  1684. ; AL - Color of the text
  1685. ; DX - Startptr to text
  1686.  
  1687. PROC draw_burning_text
  1688.  
  1689.     MOV     ES,firestartscr         ; Draw here
  1690.     
  1691.     MOV     BX,35216                ; Startoffset on screen
  1692.     MOV     DI,7                    ; Startcolumn inside font
  1693.  
  1694.     MOV     color,AL                ; Save original color
  1695.  
  1696.     MOV     CX,timer                ; Randomize
  1697.     MOV     temp,CX
  1698.  
  1699. _dbt_loop:
  1700.     MOV     AL,color                ; Get color
  1701.     MOV     AH,AL
  1702.     
  1703.     MOV     SI,DX                   ; SI=Pointer to char in font
  1704.     MOVZX   SI,[SI]
  1705.     
  1706.     CMP     SI,0                    ; End of the string?
  1707.     JE      _dbt_end                ; Oh Yes -> Quit
  1708.     
  1709.     SHL     SI,4
  1710.     ADD     SI,OFFSET vga_font
  1711.     
  1712.     MOV     CX,15                   ; Loop through 16 rows
  1713.  
  1714. _dbt_column_loop:
  1715.     BT      [SI],DI                 ; Get one bit from the font
  1716.     JNC     _dbt_column_nodraw      ; Bit was 0 -> Don't draw
  1717.  
  1718.     MOV     [WORD ES:BX],AX         ; Draw 2 points
  1719.  
  1720. _dbt_column_nodraw:
  1721.     ADD     BX,320                  ; Increase y-coordinate
  1722.     INC     SI                      ; Next row in the font
  1723.  
  1724.     LOOP    _dbt_column_loop        ; Loop through all rows
  1725.  
  1726.     DEC     DI                      ; Next column in font
  1727.     JNS     _dbt_char_not_drawed    ; This char drawed?
  1728.  
  1729.     INC     DX                      ; Yes -> Next char
  1730.     MOV     DI,7
  1731.  
  1732.     MOV     AL,color                ; Get original color
  1733.     
  1734.     MOV     SI,temp                 ; Calculate random color (+/- 8)
  1735.     INC     temp                    ; For the next character
  1736.     ADD     SI,900
  1737.     MOV     CL,[SI]
  1738.     AND     CL,00001111b
  1739.     SUB     CL,6
  1740.     ADD     color,CL        
  1741.  
  1742.     CMP     color,96                ; Check palette limits
  1743.     JB      _dbt_char_not_drawed
  1744.     
  1745.     MOV     color,95
  1746.  
  1747. _dbt_char_not_drawed:
  1748.     SUB     BX,4798                 ; Next column on screen
  1749.  
  1750.     JMP     _dbt_loop               ; Loop
  1751.  
  1752. _dbt_end:
  1753.     MOV     ES,codesegment          ; Restore ES
  1754.     
  1755.     RET
  1756.         
  1757. ENDP
  1758.  
  1759.  
  1760. ; Light me up ---------------------------------------------
  1761.  
  1762. PROC light_me_up
  1763.  
  1764.     MOV     ES,virtualscr           ; Init SREGs
  1765.     MOV     DS,firestartscr
  1766.  
  1767.     MOV     DI,8000                 ; Starting offset
  1768.  
  1769. _lmu_loop:
  1770.     MOVZX   AX,[DI+320]             ; Add together 4 surrounding points
  1771.     ADD     AL,[DI+318]
  1772.     MOVZX   BX,[DI+640]
  1773.     ADD     BL,[DI+642]
  1774.     ADD     AX,BX
  1775.     
  1776.     SHR     AX,2                    ; Divide sum by 4
  1777.  
  1778.     DEC     AL                      ; Fade
  1779.     JNS     _lmu_draw
  1780.  
  1781.     MOV     AL,0
  1782.  
  1783. _lmu_draw:
  1784.     MOV     AH,AL                   ; Draw as WORDs
  1785.  
  1786.     MOV     [ES:DI],AX              ; Draw
  1787.     ADD     DI,2
  1788.     
  1789.     CMP     DI,40640                ; Done?
  1790.     JB      _lmu_loop
  1791.  
  1792.     MOV     AX,codesegment          ; Restore SREGs
  1793.     MOV     ES,AX
  1794.     MOV     DS,AX
  1795.  
  1796.     RET
  1797.  
  1798. ENDP
  1799.  
  1800.  
  1801. ; Draw mirror for the fire --------------------------------
  1802.  
  1803. PROC draw_mirror
  1804.  
  1805.     MOV     AX,virtualscr           ; Init SREGs
  1806.     MOV     ES,AX
  1807.     MOV     DS,AX
  1808.  
  1809.     MOV     SI,8000                 ; Starting offsets
  1810.     MOV     DI,56000
  1811.  
  1812. _dmirror_loop:
  1813.     MOV     CX,160                  ; Row has 160 WORDs
  1814.  
  1815. _dmirror_row_loop:
  1816.     LODSW                           ; Get color
  1817.  
  1818.     SHR     AX,1                    ; Fade color
  1819.     AND     AX,1111111101111111b
  1820.     
  1821.     STOSW                           ; Store shadow
  1822.  
  1823.     LOOP    _dmirror_row_loop       ; Loop through this row
  1824.  
  1825.     ADD     SI,320                  ; Next row
  1826.     SUB     DI,640
  1827.  
  1828.     CMP     SI,40640                ; Done?
  1829.     JB      _dmirror_loop
  1830.  
  1831.     MOV     AX,codesegment          ; Restore SREGs
  1832.     MOV     ES,AX
  1833.     MOV     DS,AX
  1834.  
  1835.     RET
  1836.  
  1837. ENDP
  1838.  
  1839.  
  1840. ; Handle burning text -------------------------------------
  1841.  
  1842. PROC handle_fire
  1843.  
  1844.     MOV     ES,virtualscr           ; Clear virtualscreen
  1845.     XOR     DI,DI
  1846.     MOV     AX,DI
  1847.     MOV     CX,64010
  1848.  
  1849.     REP STOSW
  1850.  
  1851.     MOV     ES,firestartscr         ; Clear firestartscreen
  1852.     XOR     DI,DI
  1853.     MOV     CX,64010
  1854.  
  1855.     REP STOSW
  1856.     
  1857.     CALL    flip_screen             ; Clear VGA memory
  1858.  
  1859.     CALL    init_fire_palette       ; Create palette for the fire
  1860.  
  1861.     MOV     fade_in_progress,1      ; Fade in
  1862.     MOV     fade_source,OFFSET palette
  1863.  
  1864.     MOV     timer,0                 ; Reset timer
  1865.  
  1866. _hfire_loop:
  1867.     INC     timer                   ; Advance timer
  1868.     
  1869.     CMP     timer,750               ; Time to quit?
  1870.     JA      _hfire_quit        
  1871.  
  1872.     MOV     DX,OFFSET black_palette ; NULL string offset
  1873.     
  1874.     CMP     timer,700
  1875.     JA      _hfire_draw        
  1876.  
  1877.     MOV     DX,OFFSET burning_textstring_2 ; 2nd string offset
  1878.     
  1879.     CMP     timer,375
  1880.     JA      _hfire_draw        
  1881.  
  1882.     MOV     DX,OFFSET black_palette ; NULL string offset
  1883.     
  1884.     CMP     timer,350
  1885.     JA      _hfire_draw        
  1886.  
  1887.     MOV     DX,OFFSET burning_textstring_1 ; 1st string offset
  1888.     
  1889. _hfire_draw:        
  1890.     ADD     count,12                ; Advance pointer to sinetable
  1891.     
  1892.     MOVZX   BX,count                ; Get SIN(count)
  1893.     SHL     BX,1
  1894.     MOV     AX,[WORD BX+sincos_table]
  1895.  
  1896.     SAR     AX,10                   ; Calculate color
  1897.     ADD     AX,80
  1898.     
  1899.     CALL    draw_burning_text       ; Draw text
  1900.  
  1901.     CALL    vert_retrace            ; Wait for retrace
  1902.     
  1903.     CALL    light_me_up             ; Create fire
  1904.        
  1905.     CALL    vert_retrace            ; Wait for retrace (again!)
  1906.     
  1907.     CALL    fade_palette            ; Fade in (if needed)
  1908.     
  1909.     CALL    draw_mirror             ; Draw mirror
  1910.     
  1911.     CALL    flip_screen             ; Show virtualscreen
  1912.  
  1913.     MOV     AX,virtualscr           ; Swap virtualscr & firestartscr
  1914.     XCHG    AX,firestartscr
  1915.     MOV     virtualscr,AX
  1916.     
  1917.     MOV     AH,1                    ; Check for a key
  1918.     INT     16h
  1919.     JZ      _hfire_loop             ; No key pressed -> Keep looping
  1920.  
  1921.     MOV     AH,0                    ; Get the keypress from buffer
  1922.     INT     16h
  1923.  
  1924.     MOV     timer,700               ; Quit by cheating the timer
  1925.     
  1926.     JMP     _hfire_loop             ; Loop
  1927.     
  1928. _hfire_quit:
  1929.     RET
  1930.  
  1931. ENDP
  1932.  
  1933.  
  1934. ; 3D-routines =============================================
  1935.  
  1936. ; Get sine & cosine for an angle --------------------------
  1937.  
  1938. ; AL - Angle (0 - 255)
  1939.  
  1940. ; Returns:
  1941.  
  1942. ; ECX - SIN(angle)
  1943. ; EDX - COS(angle)
  1944.  
  1945. PROC get_one_sincos
  1946.  
  1947.     MOVZX   BX,AL                   ; Get SIN(angle)
  1948.  
  1949.     SHL     BX,1                    ; Table contains WORDs
  1950.  
  1951.     MOVSX   ECX,[WORD BX+sincos_table] ; Get sine
  1952.  
  1953.     MOV     BX,64                   ; Get COS(angle)
  1954.     SUB     BL,AL                   ; = SIN(64 - angle)
  1955.  
  1956.     SHL     BX,1
  1957.  
  1958.     MOVSX   EDX,[WORD BX+sincos_table]
  1959.  
  1960.     RET
  1961.  
  1962. ENDP
  1963.  
  1964.  
  1965. ; Get all sines & cosines needed --------------------------
  1966.  
  1967. PROC get_sincos
  1968.     
  1969.     MOV     AL,x_rotation           ; Get sine & cosine of x_rotation
  1970.  
  1971.     CALL    get_one_sincos
  1972.  
  1973.     MOV     sin_x,ECX
  1974.     MOV     cos_x,EDX
  1975.  
  1976.     MOV     AL,y_rotation           ; y_rotation
  1977.  
  1978.     CALL    get_one_sincos
  1979.  
  1980.     MOV     sin_y,ECX
  1981.     MOV     cos_y,EDX
  1982.  
  1983.     MOV     AL,z_rotation           ; z_rotation
  1984.  
  1985.     CALL    get_one_sincos
  1986.  
  1987.     MOV     sin_z,ECX
  1988.     MOV     cos_z,EDX
  1989.  
  1990.     RET
  1991.  
  1992. ENDP
  1993.  
  1994.  
  1995. ; Calculate matrix ----------------------------------------
  1996.  
  1997. ; x/y/z_rotation - Angles of rotation
  1998.  
  1999. PROC calc_matrix
  2000.  
  2001.     CALL    get_sincos              ; Get sines & cosines
  2002.  
  2003.     MOV     EAX,cos_z               ; cos_z * cos_y
  2004.     IMUL    EAX,cos_y
  2005.     SAR     EAX,14
  2006.     MOV     cosz_cosy,EAX
  2007.     
  2008.     MOV     EAX,sin_z               ; sin_z * cos_y
  2009.     IMUL    EAX,cos_y
  2010.     SAR     EAX,14
  2011.     MOV     sinz_cosy,EAX
  2012.     
  2013.     MOV     EAX,sin_z               ; sin_z * cos_x
  2014.     IMUL    EAX,cos_x
  2015.     SAR     EAX,14
  2016.     MOV     sinz_cosx,EAX
  2017.     
  2018.     MOV     EAX,cos_z               ; cos_z * sin_x
  2019.     IMUL    EAX,sin_x
  2020.     SAR     EAX,14
  2021.     MOV     cosz_sinx,EAX
  2022.     
  2023.     MOV     EAX,cos_z               ; cos_z * cos_x
  2024.     IMUL    EAX,cos_x
  2025.     SAR     EAX,14
  2026.     MOV     cosz_cosx,EAX
  2027.     
  2028.     MOV     EAX,sin_z               ; sin_z * sin_x
  2029.     IMUL    EAX,sin_x
  2030.     SAR     EAX,14
  2031.     MOV     sinz_sinx,EAX
  2032.     
  2033.     MOV     EAX,cos_y               ; cos_y * sin_x
  2034.     IMUL    EAX,sin_x
  2035.     SAR     EAX,14
  2036.     MOV     cosy_sinx,EAX
  2037.     
  2038.     MOV     EAX,cos_y               ; cos_y * cos_x
  2039.     IMUL    EAX,cos_x
  2040.     SAR     EAX,14
  2041.     MOV     cosy_cosx,EAX
  2042.     
  2043.     MOV     EAX,cosz_cosy           ; matrix0 = cos_z * cos_y
  2044.     MOV     matrix0,EAX
  2045.  
  2046.     MOV     EAX,sinz_cosy           ; matrix1 = -sin_z * cos_y
  2047.     NEG     EAX
  2048.     MOV     matrix1,EAX
  2049.  
  2050.     MOV     EAX,sin_y               ; matrix2 = sin_y
  2051.     MOV     matrix2,EAX
  2052.  
  2053.     MOV     EAX,cosz_sinx           ; matrix3 = sin_z * cos_x +
  2054.     IMUL    EAX,sin_y               ;           cos_z * sin_x * sin_y
  2055.     SAR     EAX,14
  2056.     ADD     EAX,sinz_cosx
  2057.     MOV     matrix3,EAX
  2058.  
  2059.     MOV     EAX,sinz_sinx           ; matrix4 = cos_z * cos_x -
  2060.     IMUL    EAX,sin_y               ;           sin_z * sin_x * sin_y
  2061.     SAR     EAX,14
  2062.     NEG     EAX
  2063.     ADD     EAX,cosz_cosx
  2064.     MOV     matrix4,EAX
  2065.     
  2066.     MOV     EAX,cosy_sinx           ; matrix5 = -cos_y * sin_x
  2067.     NEG     EAX
  2068.     MOV     matrix5,EAX
  2069.  
  2070.     MOV     EAX,cosz_cosx           ; matrix6 = sin_z * sin_x -
  2071.     IMUL    EAX,sin_y               ;           cos_z * cos_x * sin_y
  2072.     SAR     EAX,14
  2073.     NEG     EAX
  2074.     ADD     EAX,sinz_sinx
  2075.     MOV     matrix6,EAX
  2076.  
  2077.     MOV     EAX,sinz_cosx           ; matrix7 = cos_z * sin_x +
  2078.     IMUL    EAX,sin_y               ;           sin_z * cos_x * sin_y
  2079.     SAR     EAX,14
  2080.     ADD     EAX,cosz_sinx
  2081.     MOV     matrix7,EAX
  2082.  
  2083.     MOV     EAX,cosy_cosx           ; matrix8 = cos_y * cos_x
  2084.     MOV     matrix8,EAX
  2085.  
  2086.     RET
  2087.  
  2088. ENDP
  2089.  
  2090.  
  2091. ; Rotate one point ----------------------------------------
  2092.  
  2093. ; Matrix _MUST_ be calculated first using correct x/y/z_rotation values
  2094.  
  2095. ; SI       - Pointer to 3 BYTEs (x, y, z)
  2096. ; distance - Distance of the point
  2097. ; DI       - Pointer to 3 WORDs (rotated x, y, z)
  2098.  
  2099. ; Returns:
  2100.  
  2101. ; New coordinates pointed by DI (3 WORDs)
  2102.  
  2103. PROC rotate_point
  2104.  
  2105.     MOVSX   EBX,[BYTE SI]           ; Move x to EBX
  2106.     
  2107.     MOVSX   ECX,[BYTE SI+1]         ; Move y to ECX
  2108.     
  2109.     MOVSX   EDX,[BYTE SI+2]         ; Move z to EDX
  2110.  
  2111.     MOV     EAX,EBX                 ; Rotate x-coordinate
  2112.     IMUL    EAX,matrix0
  2113.     MOV     new_x,EAX
  2114.  
  2115.     MOV     EAX,ECX
  2116.     IMUL    EAX,matrix1
  2117.     ADD     new_x,EAX
  2118.  
  2119.     MOV     EAX,EDX
  2120.     IMUL    EAX,matrix2
  2121.     ADD     new_x,EAX
  2122.  
  2123.     MOV     EAX,EBX                 ; Rotate y-coordinate
  2124.     IMUL    EAX,matrix3
  2125.     MOV     new_y,EAX
  2126.  
  2127.     MOV     EAX,ECX
  2128.     IMUL    EAX,matrix4
  2129.     ADD     new_y,EAX
  2130.  
  2131.     MOV     EAX,EDX
  2132.     IMUL    EAX,matrix5
  2133.     ADD     new_y,EAX
  2134.  
  2135.     IMUL    EBX,matrix6             ; Rotate z-coordinate
  2136.     MOV     new_z,EBX
  2137.  
  2138.     IMUL    ECX,matrix7
  2139.     ADD     new_z,ECX
  2140.  
  2141.     IMUL    EDX,matrix8
  2142.     ADD     new_z,EDX
  2143.  
  2144.     MOV     ECX,new_z               ; Calculate perspective
  2145.     ADD     ECX,distance
  2146.     SAR     ECX,8
  2147.  
  2148.     MOV     EDX,new_x               ; X-coordinate
  2149.     MOV     AX,DX
  2150.     SAR     EDX,16
  2151.     IDIV    CX
  2152.     ADD     AX,center_x
  2153.     STOSW                           ; Store new x
  2154.     
  2155.     ADD     ECX,3000                ; Stretch object horizontally
  2156.     
  2157.     MOV     EDX,new_y               ; Y-coordinate
  2158.     MOV     AX,DX
  2159.     SAR     EDX,16
  2160.     IDIV    CX
  2161.     ADD     AX,center_y
  2162.     STOSW                           ; Store new y
  2163.  
  2164.     MOV     EAX,new_z
  2165.     SAR     EAX,6
  2166.     STOSW                           ; Store new z
  2167.  
  2168.     RET
  2169.  
  2170. ENDP
  2171.  
  2172.  
  2173. ; Rotate all points ---------------------------------------
  2174.  
  2175. ; Matrix _MUST_ be calculated first using correct x/y/z_rotation values
  2176.  
  2177. ; SI    - Pointer to coordinates
  2178. ; count - Number of points to rotate
  2179.  
  2180. PROC rotate_all
  2181.  
  2182.     MOV     DI,OFFSET screen_coords ; Destination offset
  2183.  
  2184. _rot_all_loop:
  2185.     CALL    rotate_point            ; Rotate one point
  2186.  
  2187.     ADD     SI,3                    ; Next point
  2188.  
  2189.     DEC     count                   ; All gone?
  2190.     JA      _rot_all_loop
  2191.  
  2192.     RET
  2193.  
  2194. ENDP
  2195.  
  2196.  
  2197. ; Sort coordinates by distance ----------------------------
  2198.  
  2199. ; SI - Pointer to coordinates
  2200. ; CX - Number of coordinates to sort
  2201.  
  2202. PROC sort_coords
  2203.  
  2204.     MOV     BX,SI                   ; Save starting adress
  2205.  
  2206.     DEC     CX                      ; Calculate ending adress
  2207.     IMUL    CX,6
  2208.     ADD     CX,SI
  2209.  
  2210. _sort_begin:
  2211.     MOV     AX,[SI+4]               ; Get z-coordinate
  2212.     CMP     AX,[SI+10]              ; Compare to next z-coordinate
  2213.     JGE     _sort_no_swap           ; Greater already -> no swapping
  2214.  
  2215.     MOV     EAX,[SI]                ; Swap x & y
  2216.     XCHG    EAX,[SI+6]
  2217.     MOV     [SI],EAX
  2218.     MOV     AX,[SI+4]               ; Swap z
  2219.     XCHG    AX,[SI+10]
  2220.     MOV     [SI+4],AX
  2221.  
  2222.     MOV     SI,BX                   ; Start from the beginning again
  2223.     JMP     _sort_begin             ; Loop
  2224.  
  2225. _sort_no_swap:
  2226.     ADD     SI,6                    ; Compare next points
  2227.     
  2228.     CMP     SI,CX                   ; Done?
  2229.     JB      _sort_begin
  2230.  
  2231.     RET
  2232.  
  2233. ENDP
  2234.  
  2235.  
  2236. ; Morph routines ==========================================
  2237.  
  2238. ; Morph any array -----------------------------------------
  2239.  
  2240. ; SI - Offset of the original array
  2241. ; DI - Offset of the morphed array
  2242. ; CX - Lenght of the array in BYTEs
  2243.  
  2244. ; Returns:
  2245.  
  2246. ; AX - 1=Morph complete
  2247.  
  2248. PROC morph
  2249.  
  2250.     MOV     AX,1                    ; Assume morph is complete
  2251.  
  2252. _morph_loop:
  2253.     MOV     BL,[SI]
  2254.     CMP     BL,[DI]                 ; Which way to go?
  2255.     JG      _morph_inc              ; Increase destination
  2256.     JL      _morph_dec              ; Decrease
  2257.  
  2258. _morph_loop2:
  2259.     INC     SI                      ; Increase pointers
  2260.     INC     DI
  2261.  
  2262.     LOOP    _morph_loop             ; Done?
  2263.  
  2264.     RET                             ; Yep
  2265.  
  2266. _morph_inc:
  2267.     INC     [BYTE DI]               ; Increase destination
  2268.     MOV     AX,0                    ; Morph is not complete
  2269.     JMP     _morph_loop2
  2270.  
  2271. _morph_dec:
  2272.     DEC     [BYTE DI]               ; Decrease destination
  2273.     MOV     AX,0
  2274.     JMP     _morph_loop2
  2275.  
  2276. ENDP
  2277.  
  2278.  
  2279. ; Morph ball-objects --------------------------------------
  2280.  
  2281. PROC morph_balls
  2282.  
  2283.     INC     timer                   ; Increase timer
  2284.  
  2285.     CMP     timer,400               ; Do we have to morph?
  2286.     JB      _morph_balls_end        ; No -> Quit
  2287.     
  2288.     MOV     SI,morph_source         ; Object to morph to
  2289.     MOV     DI,OFFSET ball_objects  ; Current object
  2290.     MOV     CX,84
  2291.     CALL    morph                   ; Morph object
  2292.  
  2293.     CMP     AX,0                    ; Are we through with the morphing?
  2294.     JE      _morph_balls_end        ; No -> Quit
  2295.  
  2296.     MOV     timer,0                 ; Yep -> Init counter
  2297.     ADD     morph_source,84         ; Next object
  2298.     
  2299. _morph_balls_end:
  2300.     RET
  2301.  
  2302.  
  2303. ENDP
  2304.  
  2305.  
  2306. ; Morph from dot to stick ---------------------------------
  2307.  
  2308. PROC morph_to_stick
  2309.  
  2310.     MOV     SI,OFFSET on_my_way_to_flag
  2311.  
  2312.     JMP     morph_fvectors
  2313.  
  2314. ENDP
  2315.  
  2316.  
  2317. ; Morph from stick to flag --------------------------------
  2318.  
  2319. PROC morph_to_flag
  2320.  
  2321.     MOV     SI,OFFSET flag_of_finland
  2322.  
  2323.     JMP     morph_fvectors
  2324.  
  2325. ENDP
  2326.  
  2327.  
  2328. ; Morph from flag to map ----------------------------------
  2329.  
  2330. PROC morph_to_map
  2331.  
  2332.     MOV     SI,OFFSET map_of_finland
  2333.  
  2334.     JMP     morph_fvectors
  2335.  
  2336. ENDP
  2337.  
  2338.  
  2339. ; Morph from map to dot -----------------------------------
  2340.  
  2341. PROC morph_to_dot
  2342.  
  2343.     MOV     SI,OFFSET vector_end
  2344.  
  2345. ENDP
  2346.  
  2347.  
  2348. ; Morph filled vectors ------------------------------------
  2349.     
  2350. PROC morph_fvectors
  2351.     
  2352.     TEST    timer,3                 ; Slow down morphing
  2353.     JNZ     _morph_fv_end
  2354.     
  2355.     MOV     DI,OFFSET vector_start  ; Morph destination
  2356.     MOV     CX,93                   ; Lenght of data
  2357.  
  2358.     CALL    morph                   ; Morph object
  2359.  
  2360. _morph_fv_end:
  2361.     JMP     fvectors_back_here
  2362.  
  2363. ENDP
  2364.  
  2365.  
  2366. ; Data ====================================================
  2367.  
  2368. DATASEG
  2369.  
  2370. ; Partial palette
  2371.  
  2372. colors:
  2373.     DB      17,00,00,26,00,00,35,00,00,44,00,00
  2374.     DB      53,00,00,63,00,00,63,32,32,63,51,51
  2375.     DB      00,20,00,31,63,31,00,00,15,63,15,15
  2376.     DB      27,27,12,39,39,12,52,52,07,63,63,00
  2377.  
  2378.  
  2379. ; Texts for the dot-scroll
  2380.  
  2381. dot_text:
  2382.  
  2383. ;        DB      "  Welcome to ""Smooth Motion"", an 4Kb-Intro released at ASSEMBLY '95.                    "
  2384. ;        DB      "Since no credits were allowed, we'd like to quote "
  2385. ;        DB      "the legendary Mr. J. Morrison:                    "
  2386. ;        DB      "......show me the way to the next whiskey bar, "
  2387. ;        DB      "but Oh, don't ask why......                    "
  2388. ;        DB      "Sorry, running out of space, must loop now......                      "
  2389.  
  2390.     
  2391.     DB      "  Welcome to ""Smooth Motion"", an 4Kb-Intro released at ASSEMBLY '95.                    "
  2392.     DB      "This incredible (!) intro is a PULP production......                   "
  2393.     DB      "Credits:                    "
  2394.         DB      "** Kimmy - Design, Coding, GFX **                    "
  2395.     DB      "** Mr. Pink - GFX, Ideas **                    "
  2396.     DB      "** Mr. Purple - GFX **                    "
  2397.     DB      "** Dabsa - Hardware **                    "
  2398.     DB      "Sorry, running out of space, must loop now......                    "
  2399.          
  2400.     DB      0
  2401.  
  2402.  
  2403. ; Sinus-scroll stuff
  2404.  
  2405. sintext_balls:
  2406.     DB      "                      WELCOME TO THE ASSEMBLY '95 4Kb-INTRO COMPETITION. "
  2407.     DB      "LET'S START WITH SOME VECTORBALLS...... ", 0
  2408.  
  2409. sintext_fvectors:
  2410.     DB      "                      NEXT: A DEDICATION TO KING MARA...... ", 0
  2411.     
  2412. sintext_wormie:
  2413.     DB      "                      STILL MORE TO COME ???          SURE, A COOL WORMIE...... ", 0
  2414.     DB      "                      "
  2415.  
  2416. sinus_colors:
  2417.     DB      31, 31, 31, 30, 30, 29, 28, 13, 60, 70, 80, 90, 95, 95, 95, 95
  2418.  
  2419.  
  2420. ; Endmessages
  2421.  
  2422. burning_textstring_1:
  2423.     DB      7, "THAT'S", 7, "ALL", 7, "FOLKS", 7, 0
  2424.  
  2425. burning_textstring_2:
  2426. ;        DB      7, "HOPE", 7, "YA", 7, "LIKED", 7, "IT", 7, 0
  2427.  
  2428.     DB      7, "PULP", 7, 7, "PRODUCTION", 7, 0
  2429.  
  2430.  
  2431.     
  2432. ;        DB      1
  2433. end_text:
  2434. ;        DB      "──┼─┼┼╢ Smooth Motion (VOTE US!) ╟┼┼─┼──", 10, 10, 13
  2435.  
  2436.     DB      "──┼─┼┼╢ Smooth Motion by PULP ╟┼┼─┼──", 10, 10, 13
  2437.  
  2438. end_text_end:
  2439.  
  2440.  
  2441. ; First quadrant of the sincos-table
  2442.  
  2443. partial_sincos:
  2444.     DW           0,   402,   804,  1205,  1606,  2006,  2404,  2801
  2445.     DW        3196,  3590,  3981,  4370,  4756,  5139,  5520,  5897
  2446.     DW        6270,  6639,  7005,  7366,  7723,  8076,  8423,  8765
  2447.     DW        9102,  9434,  9760, 10080, 10394, 10702, 11003, 11297
  2448.     DW       11585, 11866, 12140, 12406, 12665, 12916, 13160, 13395
  2449.     DW       13623, 13842, 14053, 14256, 14449, 14635, 14811, 14978
  2450.     DW       15137, 15286, 15426, 15557, 15679, 15791, 15893, 15986
  2451.     DW       16069, 16143, 16207, 16261, 16305, 16340, 16364, 16379
  2452.     DW       16383
  2453.  
  2454.  
  2455. ; Vectorball-objects (28 balls each)
  2456.  
  2457. ball_objects:
  2458.  
  2459. ; Circle
  2460.     DB      -50, 0, 0, -42,  30, 0, -16,  48, 0,  16,  48, 0,  42,  30, 0
  2461.     DB       50, 0, 0,  42, -30, 0,  16, -48, 0, -16, -48, 0, -42, -30, 0
  2462.     
  2463.     DB      -50, 0, 0, -42,  30, 0, -16,  48, 0,  16,  48, 0,  42,  30, 0
  2464.     DB       50, 0, 0,  42, -30, 0,  16, -48, 0, -16, -48, 0, -42, -30, 0
  2465.     DB      -50, 0, 0, -42,  30, 0, -16,  48, 0,  16,  48, 0,  42,  30, 0
  2466.     DB       50, 0, 0,  42, -30, 0,  16, -48, 0
  2467.  
  2468.  
  2469. ; Flat
  2470.     DB      -50, -50, 0, -25, -50, 0, 0, -50, 0, 25, -50, 0, 50, -50, 0
  2471.     DB      -50, -25, 0, -25, -25, 0, 0, -25, 0, 25, -25, 0, 50, -25, 0
  2472.     DB      -50,   0, 0, -25,   0, 0,            25,   0, 0, 50,   0, 0
  2473.     DB      -50,  25, 0, -25,  25, 0, 0,  25, 0, 25,  25, 0, 50,  25, 0
  2474.     DB      -50,  50, 0, -25,  50, 0, 0,  50, 0, 25,  50, 0, 50,  50, 0
  2475.     
  2476.     DB      -50, -50, 0, -25, -50, 0, 0, -50, 0, 25, -50, 0
  2477.  
  2478. ; Box
  2479.     DB      -40,  40,  40, -15,  40,  40, 15,  40,  40, 40,  40,  40
  2480.     DB      -40, -40,  40, -15, -40,  40, 15, -40,  40, 40, -40,  40
  2481.     DB      -40,  40, -40, -15,  40, -40, 15,  40, -40, 40,  40, -40
  2482.     DB      -40, -40, -40, -15, -40, -40, 15, -40, -40, 40, -40, -40
  2483.     DB      -40,  40,  15, -40,  40, -15, 40,  40,  15, 40,  40, -15
  2484.     DB      -40, -40,  15, -40, -40, -15, 40, -40,  15, 40, -40, -15
  2485.     DB       15,   0,  15, -15,   0,  15, 15,   0, -15, -15,  0, -15
  2486.     
  2487. ; Asm
  2488.     DB      -50,  30, 0, -40,  30, 0
  2489.     DB      -60,  20, 0, -30,  20, 0,   0,  20, 0,  10,  20, 0, 36,  20, 0, 53,  20, 0
  2490.     DB      -60,  10, 0, -30,  10, 0, -12,  10, 0,   0,   5, 0, 30,  10, 0, 45,  10, 0, 60, 10, 0
  2491.     DB      -60,   0, 0, -50,   0, 0, -40,   0, 0, -30,   0, 0, 10,  -2, 0, 30,   0, 0, 60,  0, 0
  2492.     DB      -60, -10, 0, -30, -10, 0, -10, -10, 0,   0, -10, 0, 30, -10, 0, 60, -10, 0
  2493.  
  2494. ; 95
  2495.     DB      -40,  30, 0, -30,  30, 0,  10, 30, 0, 20, 30, 0, 30, 30, 0, 40, 30, 0
  2496.     DB      -50,  20, 0, -20,  20, 0,  10, 20, 0
  2497.     DB      -50,  10, 0, -20,  10, 0,  10, 10, 0, 20, 10, 0, 30, 10, 0
  2498.     DB      -40,   0, 0, -30,   0, 0, -20,  0, 0, 40,  0, 0
  2499.     DB      -20, -10, 0,  40, -10, 0
  2500.     DB      -50, -20, 0, -20, -20, 0,  10, -20, 0, 40, -20, 0
  2501.     DB      -40, -30, 0, -30, -30, 0,  20, -30, 0, 30, -30, 0
  2502.  
  2503.  
  2504. ; Vector-objects
  2505.  
  2506. on_my_way_to_flag:
  2507.     DB      0,   0, 0, 0,   0, 0, 0, -25, 0, 0, -25, 0
  2508.     DB      0, -25, 0, 0, -25, 0, 0,   0, 0, 0,   0, 0
  2509.  
  2510.     DB      0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 25, 0, 0, 25, 0, 0, 0, 0
  2511.  
  2512.     DB      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  2513.  
  2514.     DB      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  2515.  
  2516.     DB      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  2517.  
  2518.     DB      0, -25, 0, 0, 25, 0, 0, 25, 0, 0, -25, 0
  2519.  
  2520. flag_of_finland:
  2521.     DB       32,   0, 0,  32,   0, 0,  32, -50, 0,  32, -50, 0
  2522.     DB      -32, -50, 0, -32, -50, 0, -32,   0, 0, -32,   0, 0
  2523.     
  2524.     DB      -32,  0, 0, -32,  0, 0, -32, 50, 0
  2525.     DB       32, 50, 0,  32, 50, 0,  32,  0, 0
  2526.  
  2527.     DB      0, 40, 0, 0, 50, 0, 32, 50, 0, 32, 50, 0, 32, 40, 0
  2528.  
  2529.     DB      -32, 40, 0, -32, 50, 0, -5, 50, 0, -5, 40, 0
  2530.  
  2531.     DB      -33, -25, 0, -33, -10, 0, 33, -10, 0, 33, -25, 0
  2532.     
  2533.     DB       -8, -51, 0,  -8,  51, 0,  8,  51, 0,  8, -51, 0
  2534.  
  2535. map_of_finland:
  2536.     DB       17,   0, 0,  26, -24, 0,  20, -40, 0,  8, -52, 0
  2537.     DB      -15, -58, 0, -28, -47, 0, -25, -22, 0, -5,   3, 0
  2538.  
  2539.     DB      -5,  3, 0, -11, 16, 0, -12, 44, 0
  2540.     DB      10, 42, 0,  15, 30, 0,  17,  0, 0
  2541.  
  2542.     DB      -4, 41, 0, 2, 55, 0, 8, 60, 0, 13, 55, 0, 10, 42, 0
  2543.     
  2544.     DB      -22, 47, 0, -20, 52, 0, -9, 42, 0, -10, 35, 0
  2545.  
  2546.     DB       -7, -55, 0, -16, -47, 0, -7, -47, 0,  2, -47, 0
  2547.     DB      -10, -48, 0, -10, -30, 0, -4, -30, 0, -4, -48, 0
  2548.  
  2549.     
  2550. ; Sprites (ball, smaller ball, shadow & worm-dot)
  2551.  
  2552. sprites:
  2553.     DB      004,000,010,000,169,000,047,001,097,001,013,011,003,007,016,017
  2554.     DB      017,017,017,017,016,003,000,001,011,016,018,018,019,019,019,019
  2555.     DB      019,017,017,016,001,000,001,011,018,019,021,021,021,021,020,020
  2556.     DB      019,018,017,001,000,000,013,018,019,021,022,023,022,021,021,020
  2557.     DB      019,019,018,017,000,013,018,019,021,023,023,023,021,021,020,020
  2558.     DB      019,018,017,000,013,018,019,021,022,023,022,021,021,020,020,019
  2559.     DB      018,017,000,013,018,019,020,021,021,021,021,020,020,019,019,018
  2560.     DB      017,000,013,018,019,019,020,020,020,020,020,019,019,018,018,017
  2561.     DB      001,011,017,019,019,019,019,019,019,018,018,018,017,001,000,001
  2562.     DB      011,016,017,017,018,018,018,018,018,017,017,016,001,000,003,007
  2563.     DB      016,017,017,017,017,017,016,003,000,012,010,003,006,016,017,017
  2564.     DB      017,017,016,003,000,001,010,016,018,018,018,018,018,018,017,017
  2565.     DB      016,001,000,001,010,018,019,021,021,021,020,019,018,018,017,001
  2566.     DB      000,000,012,016,019,021,021,022,021,021,020,019,018,017,016,000
  2567.     DB      012,018,019,021,022,022,022,021,020,019,018,018,017,000,012,018
  2568.     DB      019,021,021,022,021,021,020,019,018,018,017,000,012,016,019,019
  2569.     DB      021,021,021,020,020,019,018,017,016,001,010,017,018,019,020,020
  2570.     DB      019,019,018,018,017,001,000,001,010,016,017,017,018,018,018,018
  2571.     DB      017,017,016,001,000,003,006,016,017,017,017,017,016,003,000,011
  2572.     DB      004,002,007,026,026,026,026,026,026,026,002,000,000,011,026,026
  2573.     DB      026,026,026,026,026,026,026,026,026,000,011,026,026,026,026,026
  2574.     DB      026,026,026,026,026,026,002,007,026,026,026,026,026,026,026,002
  2575.     DB      000,013,010,004,005,023,023,023,023,023,004,000,002,009,023,023
  2576.     DB      022,022,022,022,022,022,021,002,000,001,011,023,022,022,022,027
  2577.     DB      027,027,021,021,021,020,001,000,001,011,023,022,027,027,027,027
  2578.     DB      027,027,021,021,020,001,000,000,013,023,022,022,027,027,027,027
  2579.     DB      027,027,021,020,020,019,000,013,023,022,027,027,027,027,027,027
  2580.     DB      021,021,020,019,019,001,011,022,021,021,027,027,021,021,021,020
  2581.     DB      020,019,001,000,001,011,022,021,021,021,021,021,020,020,020,019
  2582.     DB      019,001,000,002,009,021,020,020,020,020,020,019,019,019,002,000
  2583.     DB      004,005,019,019,019,019,019,004,000
  2584.  
  2585.  
  2586. ; Undefined data ==========================================
  2587.  
  2588. UDATASEG
  2589.  
  2590. vga_palette:
  2591.     DB      288 DUP (?)             ; Space for palettes (96 colors each)
  2592.  
  2593. palette:
  2594.     DB      288 DUP (?)
  2595.  
  2596. black_palette:
  2597.     DB      288 DUP (?)
  2598.  
  2599. vector_start:
  2600.     DB      100 DUP (?)             ; First fvector-object
  2601.  
  2602. vector_end:
  2603.     DB      100 DUP (?)             ; Last fvector-object
  2604.  
  2605. cga_font:
  2606.     DB      1024 DUP (?)            ; Space for the CGA 8*8 font
  2607.  
  2608. vga_font:
  2609.     DB      2048 DUP (?)            ; Space for the VGA 8*14 font
  2610.  
  2611. sincos_table:
  2612.     DW      256 DUP (?)             ; Space for the full sincos-table
  2613.  
  2614. screen_coords:
  2615.     DW      100 DUP (?)             ; Space for the screen coordinates
  2616.  
  2617. pg_table:
  2618.     DW      400 DUP (?)             ; Table for polygon-drawing
  2619.  
  2620. starfield_data:
  2621.     DB      300 DUP (?)             ; Space for stars
  2622.  
  2623. END
  2624.  
  2625.    
  2626.    That's all folks...
  2627.  
  2628.    Elvis lives!
  2629.